package com.hk.service.impl;

import com.hk.commons.*;
import com.hk.commons.entity.LogUtil;
import com.hk.commons.entity.Safety;
import com.hk.commons.entity.product.ProductInfo;
import com.hk.commons.vo.CheckInfo;
import com.hk.commons.vo.ProdPayBackPhoneInfo;
import com.hk.dao.base.impl.BaseServiceImpl;
import com.hk.service.IMsg;
import com.hk.service.ISafety;
import com.hk.service.kyc.ILogUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Random;

@Service
public class SafetyImpl extends BaseServiceImpl<Safety> implements ISafety {

	private Logger logger = LoggerFactory.getLogger(SafetyImpl.class);

	@Autowired
	private ILogUtil logService;

	@Autowired
	private IMsg msgService;



	@Override
	public Safety getByKey(String key) {
		HqlFilter hqlFilter = new HqlFilter();
		hqlFilter.addEQFilter("keyName", key );
		return getByFilter(hqlFilter);
	}

	@Override
	public Safety getById(int id) {
		return super.getById(id);
	}


	@Override
	public void  addPayBackLogRecord(Long userId, Safety before, Safety after){
		logger.info("will add addPayBackLogRecord ");

		try{
			LogUtil logRecord = new LogUtil();

			logRecord.setActUserId(userId);
			logRecord.setType(ConstantLog.LOG_TYPE_SAFETY_PAYBACK_PHONE);
			logRecord.setChgDesc("修改回款划拨授权码接收设置");



			logRecord.setRecordId(Long.valueOf(before.getId()));



			ProdPayBackPhoneInfo info = new ProdPayBackPhoneInfo();
			info.setPhone01(before.getField01());
			info.setPhone02(before.getField02());
			info.setMail01(before.getField03());
			info.setMail02(before.getField04());


			// 在日志表中保存修改之前的镜像
			String beforeImgStr = JsonUtils.toJson(info);

			logRecord.setBeforeImg(beforeImgStr);
			ProdPayBackPhoneInfo infoAf = new ProdPayBackPhoneInfo();
			infoAf.setPhone01(after.getField01());
			infoAf.setPhone02(after.getField02());
			infoAf.setMail01(after.getField03());
			infoAf.setMail02(after.getField04());

			logger.info("更改回款划拨验证手机号 更改前 phone01={}, phone02={}, 更改后 phone01={}, phone02={}",
					before.getField01(), before.getField02(), after.getField01(), after.getField02());

			// 在日志中保存修改之后的镜像
			String afterImgStr = JsonUtils.toJson( infoAf);
			logRecord.setAfterImg(afterImgStr);

			// 加入日志表中
			logService.add(logRecord);

		}catch (Exception e){
			logger.error("更改回款划拨验证手机号，添加日志错误 e={}", e);
		}

	}

	@Override
	public void addUpdateLog(Long userId, Safety before, Safety after){
		logger.info("will add safetyLogRecord ");
		try{
			LogUtil logRecord = new LogUtil();

			logRecord.setActUserId(userId);
			logRecord.setType(ConstantLog.LOG_TYPE_SAFETY);
			logRecord.setChgDesc("修改安全接收设置");

			logRecord.setRecordId(Long.valueOf(before.getId()));

			// 在日志表中保存修改之前的镜像
			String beforeImgStr = JsonUtils.toJson(before);
			logRecord.setBeforeImg(beforeImgStr);

			//在日志表中保存修改后的镜像
			String afterImgStr = JsonUtils.toJson(after);
			logRecord.setAfterImg(afterImgStr);
			// 加入日志表中
			logService.add(logRecord);

		}catch (Exception e){
			logger.error("更改安全设置-二重验证，添加日志错误 e={}", e);
		}
	}

	/**
	 * 发送销户验证码
	 * @param userName
	 * @return
	 */
	@Override
	public CheckInfo sendCloseAccountCode(String userName,String phone) {
		Safety safety = getByKey(ConstantSafety.SAFETY_CLOSE_ACCOUNT);
		CheckInfo checkInfo = new CheckInfo();

		if(safety == null || StringHelper.isEmpty(safety.getField01()) || StringHelper.isEmpty(safety.getField02())){
			checkInfo.setResult(false);
			checkInfo.setResultMsg("安全设置中销户验证手机号码不存在，短信验证码发送失败！");
			return checkInfo;
		}

		try{
			String info = userName;
			if(StringUtils.isBlank(userName)){
				info = phone;
			}

			String phone01 = safety.getField01();
			String phone02 = safety.getField02();
			String mail01  = safety.getField03();
			String mail02 = safety.getField04();

			Random random = new Random();
			String code01 = "";
			String code02 = "";
			for (int i = 0; i < 6; i++) {
				code01 += random.nextInt(10);
			}

			for (int i = 0; i < 6; i++) {
				code02 += random.nextInt(10);
			}

			RedisCilent.setString(CacheConstants.MOBLIE_MSG_CODE + phone01, code01, 5*60);

			RedisCilent.setString(CacheConstants.MOBLIE_MSG_CODE + phone02, code02, 5*60);
			String content01 = "【华康海宇财富】用户销户验证短信,用户信息："+ info + " 第1个短信验证码：" + code01 + ", 5分钟内有效";
			String content02 = "【华康海宇财富】用户销户验证短信,用户信息："+ info + " 第2个短信验证码：" + code02 + ", 5分钟内有效";
			Boolean result01 = msgService.sendMsg(phone01, content01);

			EmailRes res01 = new EmailRes();
			res01.setSubject("销户");
			res01.setText(content01);
			res01.setToName(mail01);
			msgService.sendMail(res01);
			Boolean result02 = msgService.sendMsg(phone02, content02);


			EmailRes res02 = new EmailRes();
			res02.setSubject("销户");
			res02.setText(content02);
			res02.setToName(mail02);
			msgService.sendMail(res02);

			if(result01 == false || result02 == false){
				logger.info("销户短信验证码发送失败");
				checkInfo.setResultMsg("销户短信验证码发送失败");
				checkInfo.setResult(false);
				return  checkInfo;
			}

			checkInfo.setResult(true);
			logger.info("短信验证码发送成功");

		}catch (Exception e){
			logger.error("发送销户短信验证码异常！");
		}
		return  checkInfo;
	}


	/**
	 * 发送回款验证短信
	 * @return
	 */
	public CheckInfo sendPayBackMsgCode(String productName){

		Safety safety =  getByKey(ConstantSafety.SAFETY_PAY_BACK);
		CheckInfo checkInfo = new CheckInfo();

		if(safety == null || StringHelper.isEmpty(safety.getField01()) || StringHelper.isEmpty(safety.getField02())){
			checkInfo.setResult(false);
			checkInfo.setResultMsg("安全设置中回款验证手机号码不存在，短信验证码发送失败！");
			return checkInfo;
		}

		String phone01 = safety.getField01();
		String phone02 = safety.getField02();
		String mail01  = safety.getField03();
		String mail02 = safety.getField04();


		Random random = new Random();
		String code01 = "";
		String code02 = "";
		for (int i = 0; i < 6; i++) {
			code01 += random.nextInt(10);
		}

		for (int i = 0; i < 6; i++) {
			code02 += random.nextInt(10);
		}


		RedisCilent.setString(CacheConstants.MOBLIE_MSG_CODE + phone01, code01, 5*60);

		RedisCilent.setString(CacheConstants.MOBLIE_MSG_CODE + phone02, code02, 5*60);

		String content01 ="【华康海宇财富】产品回款验证短信， 产品名称："+ productName + " 第1个短信验证码：" + code01 + ", 5分钟内有效";

		String content02 ="【华康海宇财富】产品回款验证短信， 产品名称："+ productName + " 第2个短信验证码：" + code02+ ",  5分钟内有效";

		Boolean result01 = msgService.sendMsg(phone01, content01);

		EmailRes res01 = new EmailRes();
		res01.setSubject(productName + "回款划拨验证码-01");
		res01.setText(content01);
		res01.setToName(mail01);
		msgService.sendMail(res01);
		Boolean result02 = msgService.sendMsg(phone02, content02);


		EmailRes res02 = new EmailRes();
		res02.setSubject(productName + "回款划拨验证码-02");
		res02.setText(content02);
		res02.setToName(mail02);
		msgService.sendMail(res02);

		if(result01 == false || result02 == false){
			logger.info("回款短信验证码发送失败");
			checkInfo.setResultMsg("回款短信验证码发送失败");
			checkInfo.setResult(false);
			return  checkInfo;
		}

		checkInfo.setResult(true);
		logger.info("短信验证码发送成功");
		return  checkInfo;
	}

	/**
	 * 检查回款验证短信
	 * @param inputCode01
	 * @param inputCode02
	 * @return
	 */
	public CheckInfo checkPayBackMsgCode(String inputCode01,  String inputCode02){

		Safety safety = getByKey(ConstantSafety.SAFETY_PAY_BACK);

		String phoneNum01 = safety.getField01();

		String phoneNum02 = safety.getField02();

		CheckInfo checkInfo = new CheckInfo();

		String msgCode01 = RedisCilent
				.getString(CacheConstants.MOBLIE_MSG_CODE + phoneNum01);

		String msgCode02 = RedisCilent
				.getString(CacheConstants.MOBLIE_MSG_CODE + phoneNum02);


		Boolean checkResult01 = StringUtils.equalsIgnoreCase(msgCode01, inputCode01);

		Boolean checkResult02 = StringUtils.equalsIgnoreCase(msgCode02, inputCode02);


		RedisCilent.delKey(CacheConstants.MOBLIE_MSG_CODE + phoneNum01);

		RedisCilent.delKey(CacheConstants.MOBLIE_MSG_CODE + phoneNum02);

		if(checkResult01 == false || checkResult02 == false){
			checkInfo.setResult( false);
			checkInfo.setResultMsg("回款短信验证码校验错误，请重试");
			return checkInfo;
		}

		checkInfo.setResult(true);

		return checkInfo;
	}

	/**
	 * 检查二重验证码
	 * @param code01
	 * @param code02
	 * @param keyName
	 * @return
	 */
	@Override
	public CheckInfo checkCode(String code01, String code02, String keyName) {
		Safety safety = getByKey(keyName);
		String phoneNum01 = safety.getField01();
		String phoneNum02 = safety.getField02();
		CheckInfo checkInfo = new CheckInfo();

		Boolean check01 = checkCode(phoneNum01,code01);
		Boolean check02 = checkCode(phoneNum02,code02);
		if(check01 == false || check02 == false){
			checkInfo.setResult(false);
			checkInfo.setResultMsg("验证码错误");
			return checkInfo;
		}
		checkInfo.setResult(true);
		return checkInfo;
	}


	/**
	 * 更新产品回款划拨错误次数
	 * @param prod
	 */
	public void updErrorNum(ProductInfo prod ){
		String key = "PRODUCT_PAYBACK_ERROR_" + prod.getId();

		Integer errorNum = updateCodeErrorNum(key);

		Safety safety =  getByKey(ConstantSafety.SAFETY_PAY_BACK);

		String phoneNum01 = safety.getField01();

		String phoneNum02 = safety.getField02();


		String content ="【华康海宇财富】回款验证信息，产品名称："+ prod.getName() + " 正在进行回款操作，短信验证码校验已错误：" + errorNum + "次, 请注意！";

		logger.info("content = " + content);
		msgService.sendMsg(phoneNum01,  content);

		msgService.sendMsg(phoneNum02,  content);
	}

	private Integer updateCodeErrorNum(String key) {
		Integer errorNum;
		if(RedisCilent.existsKey(key)){
			String errNumStr = RedisCilent.getString(key);
			if(StringHelper.isNotEmpty(errNumStr)){
				errorNum = Integer.valueOf(errNumStr);
				errorNum++;

				RedisCilent.setString(key, errorNum.toString(), 30* 60);

			}else{
				errorNum = 1;
				RedisCilent.setString(key, "1", 30* 60);
			}
		}else{
			errorNum = 1;
			RedisCilent.setString(key, "1", 30* 60);
		}
		return errorNum;
	}


	/**
	 * 获取产品回款划拨错误次数
	 * @param productId
	 * @return
	 */
	public Integer getErrorNum(Long productId){
		String key = "PRODUCT_PAYBACK_ERROR_" + productId;
		Integer errorNum = 0;
		if(RedisCilent.existsKey(key)){
			String errNumStr = RedisCilent.getString(key);
			if(StringHelper.isNotEmpty(errNumStr)){
				errorNum = Integer.valueOf(errNumStr);
			}
		}

		return errorNum;
	}

	/**
	 * 检查产品回款划拨错误次数
	 * @param productId
	 * @return
	 */
	public  CheckInfo checkErrorNum(Long productId){
		CheckInfo checkInfo = new CheckInfo();

		Integer errorNum = getErrorNum(productId);
		if(errorNum >5){
			checkInfo.setResult(false);
			checkInfo.setResultMsg("进入产品回款划拨接口，检查短信验证码输入错误次数大于5次，回款划拨冻结中，请稍后尝试。");
			return  checkInfo;
		}

		checkInfo.setResult(true);
		return checkInfo;
	}

	/**
	 * 检查验证码错误次数
	 * @param actUserId 操作人的id
	 * @return
	 */
	@Override
	public CheckInfo checkCodeErrorNum(Long actUserId) {
		CheckInfo checkInfo = new CheckInfo();
		String key = "SAFETY_CODE_CHECK_" + actUserId;
		Integer errorNum = 0;
		if(RedisCilent.existsKey(key)){
			String errNumStr = RedisCilent.getString(key);
			if(StringHelper.isNotEmpty(errNumStr)){
				errorNum = Integer.valueOf(errNumStr);
			}
		}
		if(errorNum >5){
			checkInfo.setResult(false);
			checkInfo.setResultMsg("验证码输入错误次数大于5次，本次操作失败,请稍后尝试。");
			return  checkInfo;
		}

		checkInfo.setResult(true);
		return checkInfo;
	}

	@Override
	public void updateCodeErrorNum(Long actUserId) {
		String key = "SAFETY_CODE_CHECK_" + actUserId;
		updateCodeErrorNum(key);
	}

	private Boolean checkCode(String phone,String code){
		String msgCode = RedisCilent.getString(CacheConstants.MOBLIE_MSG_CODE + phone);
		Boolean result = StringUtils.equalsIgnoreCase(msgCode, code);
		RedisCilent.delKey(CacheConstants.MOBLIE_MSG_CODE + phone);
		return  result;
	}
}
